package com.mspbots.core.bot.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.mspbots.core.AbstractBaseServiceImpl;
import com.mspbots.core.bot.mapper.SystemBotMapper;
import com.mspbots.core.bot.mapper.TenantBotMapper;
import com.mspbots.core.bot.model.SystemBot;
import com.mspbots.core.bot.model.SystemBotDTO;
import com.mspbots.core.bot.model.TenantBot;
import com.mspbots.core.bot.service.SystemBotService;
import com.mspbots.core.script.model.SystemScript;
import com.mspbots.core.script.model.TenantScript;
import com.mspbots.core.script.service.SystemScriptService;
import com.mspbots.core.script.service.TenantScriptService;
import com.mspbots.core.wise.mapper.TenantMapper;
import com.mspbots.core.wise.model.Tenant;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * com.mspbots.core.bot.service.impl.SystemBotImpl
 *
 * @author Jason
 * @date 2019/12/19
 **/
@Service
public class SystemBotImpl extends AbstractBaseServiceImpl<SystemBotMapper, SystemBot> implements SystemBotService {
    @Autowired
    private TenantBotMapper tenantBotMapper;
    @Autowired
    private TenantMapper tenantMapper;
    @Autowired
    private SystemScriptService systemScriptService;
    @Autowired
    private TenantScriptService tenantScriptService;

    @Transactional
    @Override
    public SystemBotDTO insertOrUpdate(SystemBotDTO entity) {
        boolean result = saveOrUpdate(entity);

        if (result) {
            List<Tenant> tenants = tenantMapper.selectList(Wrappers.emptyWrapper());
            if (!CollectionUtils.isEmpty(entity.getSystemScriptList())) {
                entity.getSystemScriptList().parallelStream().forEach(systemScript -> systemScript.setBotId(entity.getId()));
                systemScriptService.saveOrUpdateBatch(entity.getSystemScriptList());
                entity.getSystemScriptList().parallelStream().filter(SystemScript::getApplyTenant).forEach(systemScript -> {

                    tenants.parallelStream().forEach(tenant -> {

                        TenantScript tenantScript = tenantScriptService.getOne(
                                Wrappers.<TenantScript>lambdaQuery()
                                        .eq(TenantScript::getSystemScriptId, systemScript.getId())
                                        .eq(TenantScript::getTenantId, tenant.getId())
                        );
                        if (tenantScript == null) {
                            tenantScript = new TenantScript();
                            BeanUtils.copyProperties(systemScript, tenantScript, "id", "create_time");
                            tenantScript.setTenantId(tenant.getId());
                            tenantScript.setSystemScriptId(systemScript.getId());
                            tenantScriptService.save(tenantScript);
                        } else if (systemScript.getVersion().equalsIgnoreCase(tenantScript.getVersion())) {
                            BeanUtils.copyProperties(systemScript, tenantScript, "id");
                            tenantScriptService.updateById(tenantScript);
                        }

                    });

                });
            }

            if (entity.isApplyTenant()) {

                tenants.parallelStream().forEach(tenant -> {
                    TenantBot tenantBot = tenantBotMapper.selectOne(Wrappers.<TenantBot>lambdaQuery().eq(TenantBot::getBotId, entity.getId()).eq(TenantBot::getTenantId, tenant.getId()));
                    if (tenantBot == null) {
                        tenantBot = new TenantBot();
                        tenantBot.setBotId(entity.getId());
                        tenantBot.setTenantId(tenant.getId());
                        tenantBot.setEnable(true);
                        tenantBot.setVersion(entity.getVersion());
                        tenantBotMapper.insert(tenantBot);
                    } else {
                        tenantBot.setVersion(entity.getVersion());
                        tenantBotMapper.updateById(tenantBot);
                    }
                });
            }

        }
        return entity;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean initTenant(String systemBotIds, Long tenantId) {
        List<SystemBot> systemBotList;
        if (StringUtils.isEmpty(systemBotIds)) {
            systemBotList = list(Wrappers.emptyWrapper());
        } else {
            List<String> ids = Lists.newArrayList(systemBotIds);
            systemBotList = listByIds(ids);
        }
        systemBotList.stream().forEach(systemBot -> {
            TenantBot tenantBot = new TenantBot();
            tenantBot.setBotId(systemBot.getId());
            tenantBot.setTenantId(tenantId);
            tenantBot.setEnable(true);
            tenantBot.setVersion(systemBot.getVersion());
            tenantBotMapper.insert(tenantBot);
            List<SystemScript> systemScriptList = systemScriptService.list(Wrappers.<SystemScript>lambdaQuery().eq(SystemScript::getBotId, systemBot.getId()));
            systemScriptList.stream().filter(SystemScript::getApplyTenant).forEach(systemScript -> {
                if (!systemScript.getScope().toLowerCase().equals("system")) {
                    TenantScript tenantScript = new TenantScript();
                    BeanUtils.copyProperties(systemScript, tenantScript, "id");
                    tenantScript.setTenantId(tenantId);
                    tenantScript.setSystemScriptId(systemScript.getId());
                    tenantScriptService.save(tenantScript);
                }
            });
        });

        return true;
    }
}
